/*
 * @Author: zhaoxiangyu@
 * @Date: 2021-11-28 19:27:48
 * @LastEditors: 647355931@qq.com
 * @LastEditTime: 2021-12-17 18:03:34
 * @Description: file content
 */
import React, { useContext, useState, useCallback, useEffect } from 'react';
import { getValueFromEvent } from '../../utils/getValueForEvent';
import FormStoreContext from './FormStoreContext';

export default function Field(props) {
  const { label, name, children } = props;
  // label 前置文字  name表单name  children Dom
  // 拿到Form传下来的FormStore实例
  const store = React.useContext(FormStoreContext);

  // 组件内部状态，用于触发组件的重新渲染
  const [value, setValue] = useState(name && store ? store.get(name) : undefined);
  // 设置一组异常
  const [error, setError] = useState(undefined);

  // 表单组件onChange事件，用于从事件中取得表单值
  const onChange = useCallback(
    (args) => {
      // args 是一个event的集合 所以要抽取出他得值 getValueFromEvent
      console.log('getValueFromEvent(args) ===> ', getValueFromEvent(args));
      return name && store && store.set(name, getValueFromEvent(args));
    },
    [name, store]
  );

  // 订阅表单数据变动
  useEffect(() => {
    if (!name || !store) return;
    // 返回一个副作用 也就是监听
    return store.subscribe((n) => {
      //   console.log('触发');
      // 当前name的数据发生了变动，获取数据并重新渲染
      if (n === name || n === '*') {
        // 切记这里不能出现 undefined 所以如果清空store之后为undefined 需要手动处理 否则无法实现重置
        setValue(store.get(name) || '');
        setError(store.errors[name] || '');
      }
    });
  }, [name, store]);

  let child = children;
  // 如果children是一个合法的组件，传入value和onChange
  if (name && store && React.isValidElement(child)) {
    const childProps = { value, onChange };
    // value, onChange 把传进来的value 和 onChange传递给child
    child = React.cloneElement(child, childProps);
  }

  return (
    <div className="agileh_ui_field">
      <label className="form__label">{label}</label>
      <div className="form__content">
        <div className="form__control">{child}</div>
        <div className="form__message">{error}</div>
      </div>
    </div>
  );
}
